home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / clang / tkern091.zip / SRC / IO.C < prev    next >
Text File  |  1994-03-13  |  10KB  |  482 lines

  1. /*
  2.  *  This file forms part of "TKERN" - "Troy's Kernel for Windows".
  3.  *
  4.  *  Copyright (C) 1994  Troy Rollo <troy@cbme.unsw.EDU.AU>
  5.  *
  6.  *  This library is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU Library General Public
  8.  *  License as published by the Free Software Foundation; either
  9.  *  version 2 of the License, or (at your option) any later version.
  10.  *
  11.  *  This library is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  *  Library General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU Library General Public
  17.  *  License along with this library; if not, write to the Free
  18.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * This module takes care of tkern file operations. Most of these
  23.  * get passed on to tkfmangr so that files can be inherited by
  24.  * child processes in tkern.
  25.  */
  26.  
  27. #include <windows.h>
  28. #include <toolhelp.h>
  29. #include <stdlib.h>
  30. #include <memory.h>
  31. #include <string.h>
  32. #include <alloc.h>
  33. #include <stdarg.h>
  34. #include <errno.h>
  35. #include <ctype.h>
  36. #include <dir.h>
  37. #include <sys/tfile.h>
  38. #include <sys/task.h>
  39. #include <sys/ioctl.h>
  40. #include <sys/wait.h>
  41. #include <sys/tkern.h>
  42.  
  43. struct    tfile    _files[TNFILE];
  44. static    HGLOBAL    hTFMem = 0;
  45. struct    tfunc    *ptf = 0;
  46.  
  47. static    int
  48. find_location(    struct task *pt,
  49.         int    *fd,
  50.         int    *ifd)
  51. {
  52.     for (*ifd = 0; *ifd < TNFILE; (*ifd)++)
  53.     {
  54.         if (!_files[*ifd].tf_cnt)
  55.             break;
  56.     }
  57.     if (*ifd == TNFILE)
  58.     {
  59.         pt->nError = EMFILE;
  60.         return -1;
  61.     }
  62.     for (*fd = 0; *fd < UFILE_MAX; (*fd)++)
  63.     {
  64.         if (pt->files[*fd] == -1)
  65.             break;
  66.     }
  67.     if (*fd == UFILE_MAX)
  68.     {
  69.         pt->nError = EMFILE;
  70.         return -1;
  71.     }
  72.     return 0;
  73. }
  74.  
  75.  
  76. int far _export
  77. tkern_open(    char const *pchFile,
  78.         int    nMode,
  79.         int    nAccess)
  80. {
  81.     int    iDevice;
  82.     int    id;
  83.     int    fd;
  84.     int    ifd;
  85.     char    const *c;
  86.     struct task *pt;
  87.     BOOL    bFile;
  88.  
  89.     pt = GetTaskInfo();
  90.     ptf->iTask = (pt - _tasks);
  91.     if (!strncmp(pchFile, "\\dev\\", 5) ||
  92.         !strncmp(pchFile, "/dev/", 5))
  93.     {
  94.         bFile = FALSE;
  95.         strcpy(ptf->achFile, pchFile + 5);
  96.         iDevice = SendMessage(hwndManager, TKWM_GETDEVNO, 0, (LPARAM) ptf);
  97.         pchFile += 5;
  98.         if ((c = strchr(pchFile, '/')) != 0)
  99.             pchFile = c + 1;
  100.     }
  101.     else
  102.     {
  103.         bFile = TRUE;
  104.         strcpy(ptf->achFile, "file");
  105.         iDevice = SendMessage(hwndManager, TKWM_GETDEVNO, 0, (LPARAM) ptf);
  106.     }
  107.  
  108.     if (find_location(pt, &fd, &ifd) == -1)
  109.         return -1;
  110.  
  111.     ptf->iDevice = iDevice;
  112.     ptf->iTask = (pt - _tasks);
  113.     if (bFile && isalpha(pchFile[0]) && pchFile[1] == ':')
  114.     {
  115.         if (pchFile[2] == '\\')
  116.         {
  117.             strcpy(ptf->achFile, pchFile);
  118.         }
  119.         else
  120.         {
  121.             strncpy(ptf->achFile, pchFile, 2);
  122.             getcurdir(toupper(pchFile[0]), ptf->achFile + 2);
  123.             if (ptf->achFile[strlen(ptf->achFile) - 1] != '\\')
  124.                 strcat(ptf->achFile, "\\");
  125.             strcat(ptf->achFile, pchFile + 2);
  126.         }
  127.     }
  128.     else
  129.     {
  130.         if (pchFile[0] == '\\')
  131.         {
  132.             getcwd(ptf->achFile, _FNLEN);
  133.             ptf->achFile[2] = '\0';
  134.             strcat(ptf->achFile, pchFile);
  135.         }
  136.         else
  137.         {
  138.             getcwd(ptf->achFile, _FNLEN);
  139.             if (ptf->achFile[strlen(ptf->achFile) - 1] != '\\')
  140.                 strcat(ptf->achFile, "\\");
  141.             strcat(ptf->achFile, pchFile);
  142.         }
  143.     }
  144.     ptf->nMode = nMode;
  145.     ptf->nAccess = nAccess;
  146.     id = SendMessage(hwndManager, TKWM_OPEN, 0, (LPARAM) ptf);
  147.     if (id == -1)
  148.         return -1;
  149.     _files[ifd].tf_cnt = 1;
  150.     _files[ifd].tf_id = id;
  151.     _files[ifd].tf_dev = iDevice;
  152.     pt->files[fd] = ifd;
  153.     return fd;
  154. }
  155.  
  156. long far _export
  157. tkern_seek(    int    fd,
  158.         long    nPosition,
  159.         int    nStart)
  160. {
  161.     struct    task *pt;
  162.  
  163.     pt = GetTaskInfo();
  164.     if (pt->files[fd] == -1)
  165.     {
  166.         pt->nError = EBADF;
  167.         return -1;
  168.     }
  169.     ptf->iDevice = _files[pt->files[fd]].tf_dev;
  170.     ptf->iTask = (pt - _tasks);
  171.     ptf->nPosition = nPosition;
  172.     ptf->nFrom = nStart;
  173.     return SendMessage(hwndManager, TKWM_SEEK,
  174.                     _files[pt->files[fd]].tf_id,
  175.                     (LPARAM) ptf);
  176. }
  177.  
  178. int far _export
  179. tkern_read(    int    fd,
  180.         char    *pchBuffer,
  181.         int    nBytes)
  182. {
  183.     struct    task *pt;
  184.     LRESULT    nRead;
  185.     int    nTotal = 0;
  186.     int    nNow;
  187.  
  188.     pt = GetTaskInfo();
  189.     if (pt->files[fd] == -1)
  190.     {
  191.         pt->nError = EBADF;
  192.         return -1;
  193.     }
  194.     if (_files[pt->files[fd]].tf_eof)
  195.     {
  196.         _files[pt->files[fd]].tf_eof = 0;
  197.         return 0;
  198.     }
  199.     while(1)
  200.     {
  201.         /*
  202.          * We set this structure up inside the loop because it is shared among
  203.          * tasks, and if we end up sleeping, another task may overwrite this
  204.          */
  205.         nNow = nBytes;
  206.         if (nNow > _FBUFSZ)
  207.             nNow = _FBUFSZ;
  208.         ptf->iDevice = _files[pt->files[fd]].tf_dev;
  209.         ptf->iTask = (pt - _tasks);
  210.         ptf->nBytes = nNow;
  211.         nRead = SendMessage(hwndManager, TKWM_READ,
  212.                     _files[pt->files[fd]].tf_id,
  213.                     (LPARAM) ptf);
  214.         if (nRead == -1)
  215.         {
  216.             return -1;
  217.         }
  218.         if (nRead != FR_NOTREADY)
  219.         {
  220.             nTotal += (int) nRead;
  221.             nBytes -= (int) nRead;
  222.             memcpy(pchBuffer, ptf->achBuffer, (int) nRead);
  223.             pchBuffer += (int) nRead;
  224.             if (!nBytes || !nRead)
  225.             {
  226.                 if (nTotal && !nRead)
  227.                     _files[pt->files[fd]].tf_eof = 1;
  228.                 return nTotal;
  229.             }
  230.         }
  231.         else if (nTotal)
  232.         {
  233.             return nTotal;
  234.         }
  235.         else
  236.         {
  237.             GetMessages(pt);
  238.         }
  239.     }
  240. }
  241.  
  242. int far _export
  243. tkern_write(    int    fd,
  244.         char const *pchBuffer,
  245.         int    nBytes)
  246. {
  247.     struct    task *pt;
  248.     int    nTotal = 0;
  249.     int    nWritten;
  250.     int    nNow;
  251.  
  252.     pt = GetTaskInfo();
  253.     if (pt->files[fd] == -1)
  254.     {
  255.         pt->nError = EBADF;
  256.         return -1;
  257.     }
  258.     while (nBytes)
  259.     {
  260.         nNow = nBytes;
  261.         if (nNow > _FBUFSZ)
  262.             nNow = _FBUFSZ;
  263.         ptf->iDevice = _files[pt->files[fd]].tf_dev;
  264.         ptf->iTask = (pt - _tasks);
  265.         memcpy(ptf->achBuffer, pchBuffer, nNow);
  266.         ptf->nBytes = nNow;
  267.         nWritten = (int) SendMessage(hwndManager, TKWM_WRITE,
  268.                         _files[pt->files[fd]].tf_id,
  269.                         (LPARAM) ptf);
  270.         if (nWritten == -1)
  271.             return -1;
  272.         if (!nWritten)
  273.             return nTotal;
  274.         nBytes -= nWritten;
  275.         nTotal += nWritten;
  276.         pchBuffer += nWritten;
  277.     }
  278.     return nTotal;
  279. }
  280.  
  281. int far _export
  282. tkern_close(    int    fd)
  283. {
  284.     struct    task *pt;
  285.     int    ifd;
  286.  
  287.     pt = GetTaskInfo();
  288.     if (pt->files[fd] == -1)
  289.     {
  290.         pt->nError = EBADF;
  291.         return -1;
  292.     }
  293.     ifd = pt->files[fd];
  294.     pt->files[fd] = -1;
  295.     if (!--_files[ifd].tf_cnt)
  296.     {
  297.         _files[ifd].tf_eof = 0;
  298.         ptf->iTask = (pt - _tasks);
  299.         ptf->iDevice = _files[ifd].tf_dev;
  300.         return SendMessage(hwndManager, TKWM_CLOSE,
  301.                         _files[ifd].tf_id,
  302.                         (LPARAM) ptf);
  303.     }
  304.     else
  305.         return 0;
  306. }
  307.  
  308. void
  309. internal_close(    int    fd,
  310.         int    iTask)
  311. {
  312.     int    ifd;
  313.  
  314.     ifd = _tasks[iTask].files[fd];
  315.         _tasks[iTask].files[fd] = -1;
  316.     if (!--_files[ifd].tf_cnt)
  317.     {
  318.         ptf->iDevice = _files[ifd].tf_dev;
  319.         ptf->iTask = iTask;
  320.         SendMessage(    hwndManager,
  321.                 TKWM_CLOSE,
  322.                 _files[ifd].tf_id,
  323.                 (LPARAM) ptf);
  324.     }
  325. }
  326.  
  327. int far _export
  328. tkern_dup(int    fd_in)
  329. {
  330.     struct    task *pt;
  331.     int    fd;
  332.  
  333.     pt = GetTaskInfo();
  334.     if (pt->files[fd_in] == -1)
  335.     {
  336.         pt->nError = EBADF;
  337.         return -1;
  338.     }
  339.     for (fd = 0; fd < UFILE_MAX; fd++)
  340.     {
  341.         if (pt->files[fd] == -1)
  342.         {
  343.             pt->files[fd] = pt->files[fd_in];
  344.             _files[pt->files[fd]].tf_cnt++;
  345.             return fd;
  346.         }
  347.     }
  348.     pt->nError = EMFILE;
  349.     return -1;
  350. }
  351.  
  352. int far _export
  353. tkern_dup2(    int    fd_in,
  354.         int    fd)
  355. {
  356.     struct    task *pt;
  357.  
  358.     pt = GetTaskInfo();
  359.     if (pt->files[fd_in] == -1)
  360.     {
  361.         pt->nError = EBADF;
  362.         return -1;
  363.     }
  364.     if (pt->files[fd] != -1)
  365.         internal_close(fd, pt - _tasks);
  366.     pt->files[fd] = pt->files[fd_in];
  367.     _files[pt->files[fd]].tf_cnt++;
  368.     return fd;
  369. }
  370.  
  371. int far _export
  372. tkern_isatty(int    fd)
  373. {
  374.     struct    task *pt;
  375.  
  376.     pt = GetTaskInfo();
  377.     if (pt->files[fd] == -1)
  378.     {
  379.         pt->nError = EBADF;
  380.         return -1;
  381.     }
  382.  
  383.     ptf->iTask = (pt - _tasks);
  384.     ptf->iDevice = _files[pt->files[fd]].tf_dev;
  385.     return SendMessage(hwndManager, TKWM_ISATTY,
  386.                     _files[pt->files[fd]].tf_id,
  387.                     (LPARAM) ptf);
  388. }
  389.  
  390. int    far _export
  391. tkern_ioctl(    int    fd,
  392.         long    nIOCtl,
  393.         char    *pchBuffer)
  394. {
  395.     int    nSize = ((nIOCtl & TK_IOCTL_PARM_SIZE) >> 16);
  396.     int    iReturn = 0;
  397.     int    ifd;
  398.     struct    task *pt;
  399.  
  400.     pt = GetTaskInfo();
  401.     ifd = pt->files[fd];
  402.     if (ifd == -1)
  403.     {
  404.         pt->nError = EBADF;
  405.         return -1;
  406.     }
  407.     if (nIOCtl & TK_IOCTL_READ_STRING)
  408.     {
  409.         strncpy(ptf->tki.achBuffer, pchBuffer, nSize - 1);
  410.         ptf->tki.achBuffer[nSize - 1] = 0;
  411.     }
  412.     else if (nIOCtl & TK_IOCTL_READ_INT)
  413.     {
  414.         memcpy(ptf->tki.achBuffer, pchBuffer, nSize);
  415.     }
  416.     ptf->iDevice = _files[ifd].tf_dev;
  417.     ptf->tki.nIOCtl = nIOCtl;
  418.     ptf->tki.nSize = nSize;
  419.     iReturn = SendMessage(hwndManager, TKWM_IOCTL, _files[ifd].tf_id, (LPARAM) ptf);
  420.     if (iReturn != -1)
  421.     {
  422.         nSize = ptf->tki.nSize;
  423.         if (nIOCtl & TK_IOCTL_WRITE_STRING)
  424.         {
  425.             strncpy(pchBuffer, ptf->tki.achBuffer, nSize - 1);
  426.             pchBuffer[nSize - 1] = 0;
  427.         }
  428.         else if (nIOCtl & TK_IOCTL_WRITE_INT)
  429.         {
  430.             memcpy(pchBuffer, ptf->tki.achBuffer, nSize);
  431.         }
  432.     }
  433.     return iReturn;
  434. }
  435.  
  436. int far _export
  437. tkern_is_device(int    fd,
  438.         char const *pchDevice)
  439. {
  440.     struct    task *pt;
  441.     int    ifd;
  442.     int    iDevice;
  443.  
  444.     pt = GetTaskInfo();
  445.     ifd = pt->files[fd];
  446.     if (ifd == -1)
  447.     {
  448.         pt->nError = EBADF;
  449.         return -1;
  450.     }
  451.     strcpy(ptf->achFile, pchDevice);
  452.     iDevice = SendMessage(hwndManager, TKWM_GETDEVNO, 0, (LPARAM) ptf);
  453.     return (_files[ifd].tf_dev == iDevice);
  454. }
  455.  
  456. void
  457. files_init(void)
  458. {
  459.     memset(_files, 0, sizeof(_files));
  460.     hTFMem = GlobalAlloc(GMEM_FIXED | GMEM_SHARE, sizeof(*ptf));
  461.     ptf = (struct tfunc *) GlobalLock(hTFMem);
  462.  
  463. }
  464.  
  465. void
  466. files_cleanup(void)
  467. {
  468.     GlobalUnlock(hTFMem);
  469.     GlobalFree(hTFMem);
  470. }
  471.  
  472. int    far _export
  473. tkern_valid_file(int fd)
  474. {
  475.     struct    task *pt;
  476.  
  477.     pt = GetTaskInfo();
  478.     return (pt->files[fd] != -1);
  479. }
  480.  
  481.  
  482.